package model

import (
	"fmt"
	"gogame/logger"
	"gogame/pb"
)

type Item struct {
	*ModelInfo
}

func init() {
	model := &Item{
		ModelInfo: NewModelInfo("item", "_id"),
	}
	model.ModelInfo.Child = model
	Manage.models.Item = model
}

// DataChange 数据改变
func (self *Item) DataChange(uid, act string, datas ...any) {
}

// ChkItemNum 检测道具是否足够
func (self *Item) ChkItemNum(uid string, itemId2Num map[string]int32) (chkRes bool, chkT string) {
	_itemId2Info := self.GetItemId2Info(uid)
	for itemId, num := range itemId2Num {
		itemInfo, ok := _itemId2Info[itemId]
		if ok {
			if itemInfo.Num < num {
				return false, itemId
			}
		} else {
			return false, itemId
		}
	}
	return true, ""
}

// DelItems 扣除道具
func (self *Item) DelItems(uid string, itemId2DelNum map[string]int32) map[string]any {
	_res := make(map[string]any)
	_itemId2Info := self.GetItemId2Info(uid)
	for itemId, delNum := range itemId2DelNum {
		_itemInfo := _itemId2Info[itemId]
		if _itemInfo == nil {
			logger.WorkerLog.Warn(fmt.Sprintf("DelItems %s 道具不足!! 请检查是否调用ChkDelNeed!", itemId))
			continue
		}

		if delNum > _itemInfo.Num {
			logger.WorkerLog.Warn(fmt.Sprintf("DelItems %s 道具数量不足!! 请检查是否调用ChkDelNeed!", itemId))
			continue
		}

		// 不可叠加道具扣除
		if len(_itemInfo.ObjectIds) > 1 {
			i := int32(0)
			for ; i < delNum; i++ {
				_delObjectId := _itemInfo.ObjectIds[i]
				self.Remove(uid, _delObjectId)
				_res[_delObjectId] = map[string]any{
					"num": 0,
				}
			}
		} else {
			_resNum := _itemInfo.Num - delNum
			_objectId := _itemInfo.ObjectIds[0]
			// 删除物品
			if _resNum == 0 {
				self.Remove(uid, _objectId)
			} else {
				_setData := map[string]any{
					"num": _resNum,
				}
				self.Set(uid, _objectId, _setData)
			}
			_res[_objectId] = map[string]any{
				"num": _resNum,
			}
		}
	}

	return _res
}

// AddItem 增加英雄
func (self *Item) AddItem(uid string, itemId string, num int32) map[string]*pb.ModelItem {
	var _oid2Item = make(map[string]*pb.ModelItem)

	_itemCon := GC.Item().Get(itemId)
	// 道具不存在
	if _itemCon == nil {
		return _oid2Item
	}

	var _anyList []any

	_nt := C.Now()
	// 创建一个新物品
	_newItem := func(isMutil bool) {
		if !isMutil {
			i := int32(0)
			for ; i < num; i++ {
				_objectId := C.GetObjectId()
				_initData := &pb.ModelItem{
					Uid:    uid,
					ItemId: itemId,
					Id:     _objectId,
					Ctime:  _nt,
					Num:    1,
				}
				_anyList = append(_anyList, _initData)
				_oid2Item[_objectId] = _initData
			}
		} else {
			_objectId := C.GetObjectId()
			_initData := &pb.ModelItem{
				Uid:    uid,
				ItemId: itemId,
				Id:     _objectId,
				Ctime:  _nt,
				Num:    num,
			}
			_anyList = append(_anyList, _initData)
			_oid2Item[_objectId] = _initData
		}

	}

	// 是否可叠加
	_isMutil := _itemCon.Ismutil
	if _isMutil {
		_itemInfo := self.GetInfo(uid, itemId)
		if _itemInfo != nil {
			_resNum := _itemInfo.Num + num
			_setData := map[string]any{
				"num": _resNum,
			}
			self.Set(uid, _itemInfo.Id, _setData)
			_oid2Item[_itemInfo.Id] = &pb.ModelItem{
				Num: _resNum,
			}
		} else {
			_newItem(true)
		}

	} else {
		_newItem(false)
	}

	if len(_anyList) > 0 {
		self.InsertMany(uid, _anyList)
	}

	return _oid2Item

}

// GetList 获取玩家道具列表
func (self *Item) GetList(uid string) []*pb.ModelItem {
	var ItemList []*pb.ModelItem
	self.ModelInfo.GetList(uid, &ItemList)

	return ItemList
}

type ItemId2Info struct {
	ObjectIds []string // 道具_id切片  用切片是因为不可叠加道具_id不一样
	Num       int32
}

// GetItemId2Info 获取道具id对应的道具详情
func (self *Item) GetItemId2Info(uid string) map[string]*ItemId2Info {
	_itemList := self.GetList(uid)
	_itemId2Info := make(map[string]*ItemId2Info)
	for _, item := range _itemList {
		itemInfo, ok := _itemId2Info[item.ItemId]
		if ok {
			itemInfo.Num += item.Num
			itemInfo.ObjectIds = append(itemInfo.ObjectIds, item.Id)
		} else {
			_itemId2Info[item.ItemId] = &ItemId2Info{
				ObjectIds: []string{item.Id},
				Num:       item.Num,
			}
		}
	}

	return _itemId2Info
}

// GetInfo 获取道具数据
func (self *Item) GetInfo(uid string, itemId string) *pb.ModelItem {
	_itemList := self.GetList(uid)
	var itemInfo *pb.ModelItem
	for _, item := range _itemList {
		if item.ItemId == itemId {
			itemInfo = item
			break
		}
	}

	return itemInfo
}
